package com.rickpan.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;

/**
 * 验证码服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CaptchaService {

    private final RedisTemplate<String, Object> redisTemplate;
    
    private static final String CAPTCHA_PREFIX = "captcha:";
    private static final int CAPTCHA_LENGTH = 4;
    private static final int CAPTCHA_EXPIRY_MINUTES = 5;
    private static final SecureRandom random = new SecureRandom();
    
    // 验证码字符集（排除容易混淆的字符）
    private static final String CAPTCHA_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /**
     * 生成验证码
     */
    public String generateCaptcha(String sessionId) {
        String code = generateRandomCode();
        
        // 存储到Redis，5分钟过期
        String key = CAPTCHA_PREFIX + sessionId;
        redisTemplate.opsForValue().set(key, code.toUpperCase(), CAPTCHA_EXPIRY_MINUTES, TimeUnit.MINUTES);
        
        log.debug("生成验证码: sessionId={}, code={}", sessionId, code);
        return code;
    }

    /**
     * 验证验证码
     */
    public boolean validateCaptcha(String sessionId, String inputCode) {
        if (sessionId == null || inputCode == null) {
            return false;
        }
        
        String key = CAPTCHA_PREFIX + sessionId;
        String storedCode = (String) redisTemplate.opsForValue().get(key);
        
        if (storedCode == null) {
            log.debug("验证码不存在或已过期: sessionId={}", sessionId);
            return false;
        }
        
        boolean isValid = storedCode.equalsIgnoreCase(inputCode.trim());
        
        if (isValid) {
            // 验证成功后删除验证码，防止重复使用
            redisTemplate.delete(key);
            log.debug("验证码验证成功: sessionId={}", sessionId);
        } else {
            log.debug("验证码验证失败: sessionId={}, expected={}, actual={}", 
                     sessionId, storedCode, inputCode);
        }
        
        return isValid;
    }

    /**
     * 删除验证码
     */
    public void removeCaptcha(String sessionId) {
        if (sessionId != null) {
            String key = CAPTCHA_PREFIX + sessionId;
            redisTemplate.delete(key);
        }
    }

    /**
     * 生成随机验证码字符串
     */
    private String generateRandomCode() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CAPTCHA_LENGTH; i++) {
            code.append(CAPTCHA_CHARS.charAt(random.nextInt(CAPTCHA_CHARS.length())));
        }
        return code.toString();
    }

    /**
     * 生成验证码图片（可选功能，前端已实现Canvas绘制）
     */
    public BufferedImage generateCaptchaImage(String code) {
        int width = 120;
        int height = 40;
        
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        
        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        // 背景色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);
        
        // 绘制字符
        g2d.setFont(new Font("Arial", Font.BOLD, 20));
        for (int i = 0; i < code.length(); i++) {
            // 随机颜色
            g2d.setColor(new Color(random.nextInt(100), random.nextInt(100), random.nextInt(100)));
            
            // 随机位置和角度
            int x = 20 + i * 25;
            int y = 25 + random.nextInt(10);
            
            g2d.drawString(String.valueOf(code.charAt(i)), x, y);
        }
        
        // 绘制干扰线
        for (int i = 0; i < 5; i++) {
            g2d.setColor(new Color(random.nextInt(200), random.nextInt(200), random.nextInt(200)));
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g2d.drawLine(x1, y1, x2, y2);
        }
        
        g2d.dispose();
        return image;
    }

    /**
     * 检查验证码是否存在
     */
    public boolean existsCaptcha(String sessionId) {
        if (sessionId == null) {
            return false;
        }
        String key = CAPTCHA_PREFIX + sessionId;
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 获取验证码剩余过期时间（秒）
     */
    public long getCaptchaExpireTime(String sessionId) {
        if (sessionId == null) {
            return 0;
        }
        String key = CAPTCHA_PREFIX + sessionId;
        Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        return expire != null ? expire : 0;
    }
}
